package com.lvmama.java.rhino.spark.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.lvmama.java.rhino.spark.entity.LogInfo;

public class LogProcessorUtil {
	private static final String DEFAULT_ENCODE = "UTF-8"; 
	
	public static boolean isNeed(String log) {
		if(StringUtils.isBlank(log)) {
			return false;
		}
		String regex = ".+FLUME-\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}.+";
		return log.matches(regex);
	}
	
	/**
	 * 获取日志的打印时间
	 * @param log 日志内容
	 * @return Date 日志的打印时间
	 */
	public static Date getPrintDate(String log) {
		if(log.length() < 24) {
			return null;
		}
		String dateStr = log.substring(0, 23);
		if(!dateStr.matches("\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2},\\d{3}")) {
			return null;
		}
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,S");
		try {
			return format.parse(dateStr);
		} catch (ParseException e) {
			return null;
		}
	}
	
	/**
	 * 将日志字符进行URLEncoder，输出的结果将不存在空格、特殊字符等字符
	 * @param str 字符串
	 * @return String 
	 */
	public static String logEncode(String str) {
		if (StringUtils.isBlank(str)) {
			return "";
		}
		try {
			str = URLEncoder.encode(str, DEFAULT_ENCODE);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str;
	}
	
	public static String logDecode(String str) {
		if (StringUtils.isBlank(str)) {
			return "";
		}
		try {
			str = URLDecoder.decode(str, DEFAULT_ENCODE);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str;
	}
	
	/**
	 * 将日志使用分隔符连接在一起
	 * @param logs 日志集合
	 * @param split 分隔符
	 * @return String 拼接好的日志信息（日志已被Encode）
	 */
	public static String concatLog(Iterable<String> logs, String split) {
		StringBuffer sb = new StringBuffer("");
		if (logs != null) {
			Iterator<String> it = logs.iterator();
			while (it.hasNext()) {
				sb.append(logEncode(it.next()) + ",");
			}
		}
		String logStr = sb.toString();
		if(logStr.endsWith(split)) {
			int endIndex = logStr.lastIndexOf(split);
			if(endIndex != -1) {
				logStr = logStr.substring(0, endIndex);
			}
		}
		return logStr;
	}
	
	/**
	 * 将日志使用分隔符连接在一起
	 * @param logs 日志集合
	 * @return String 拼接好的日志信息（日志已被Encode）
	 */
	public static String concatLog(Iterable<String> logs) {
		return concatLog(logs, ",");
	}
	
	/**
	 * 将日志按照某一个连接符撇开
	 * @param logStr 多行日志的字符串
	 * @param split 分隔符
	 * @return List 拆分好的日志集合 
	 */
	public static List<String> splitLog(String logStr, String split) {
		List<String> logList = new ArrayList<String>();
		if(StringUtils.isBlank(logStr)) {
			return logList;
		}
		String[] logs = logStr.split(split);
		for (int i = 0; i < logs.length; i++) {
			String log = logDecode(logs[i]);
			logList.add(log);
		}
		return logList;
	}
	
	/**
	 * 将日志按照某一个连接符撇开
	 * @param logStr 多行日志的字符串
	 * @return List 拆分好的日志集合
	 */
	public static List<String> splitLog(String logStr) {
		return splitLog(logStr, ",");
	}
	
	/**
	 * 检查整个线程的日志是否完成
	 * @param logList
	 * @return true-完整线程日志；false-非完整
	 */
	public static boolean isCompleteLog(List<String> logList) {
		if(logList == null || logList.isEmpty()) {
			return true;
		}
		return checkEnd(logList);
	}
	
	private static boolean checkEnd(List<String> logList) {
		String log = logList.get(logList.size()-1);
		LogInfo logInfo = LogParseUtils.parseLog(log);
		if(logInfo == null) {
			return false;
		}
		if(Constants.LOG_END_FLAG.equals(logInfo.getContent())) {
			return true;
		}
		if(logList.size() < 2) {
			return false;
		}
		LogInfo logInfo2 = LogParseUtils.parseLog(logList.get(logList.size()-2));
		if(logInfo2.getPrintTime().before(logInfo.getPrintTime())) {
			return false;
		}
		logList.remove(logList.size()-1);
		return checkEnd(logList);
	}
	
	/**
	 * 判断该行日志是否是dubbo请求日志的起始日志
	 * @param log 一条完整的日志
	 * @return
	 */
	public static boolean isDubboMethodStartLog(String log) {
		LogInfo logInfo = LogParseUtils.parseLog(log);
		if(logInfo == null) {
			return false;
		}
		return isDubboMethodStartLogContent(logInfo.getContent());
	}
	
	/**
	 * 判断该行日志是否是dubbo请求日志的起始日志
	 * @param logContent 仅仅指日志内容，已经去掉了前面的各种固定内容
	 * @return
	 */
	public static boolean isDubboMethodStartLogContent(String logContent) {
		if(StringUtils.isBlank(logContent)) {
			return false;
		}
		String regex = "interface\\s{1}=\\s{1}interface\\s{1}[\\w+.]+\\w+,\\s{1}method\\s{1}=\\s{1}\\w+\\s{1}--\\s{1}start";
		return logContent.matches(regex);
	}
	
	/**
	 * 判断该行日志是否是dubbo请求日志的结束日志
	 * @param log 一条完整的日志
	 * @return
	 */
	public static boolean isDubboMethodEndLog(String log) {
		LogInfo logInfo = LogParseUtils.parseLog(log);
		if(logInfo == null) {
			return false;
		}
		return isDubboMethodStartLogContent(logInfo.getContent());
	}
	
	/**
	 * 判断该行日志是否是dubbo请求日志的结束日志
	 * @param logContent 仅仅指日志内容，已经去掉了前面的各种固定内容
	 * @return
	 */
	public static boolean isDubboMethodEndLogContent(String logContent) {
		if(StringUtils.isBlank(logContent)) {
			return false;
		}
		String regex = "interface\\s{1}=\\s{1}interface\\s{1}[\\w+.]+\\w+,\\s{1}method\\s{1}=\\s{1}\\w+\\s{1}--\\s{1}end";
		return logContent.matches(regex);
	}
	
	public static String gzip(String str) {
		return logEncode(LvtuZipUtils.gzip(str));
	}
	
	public static String gunzip(String str) {
		return LvtuZipUtils.gunzip(logDecode(str));
	}
	
	public static void main(String[] args) {
//		System.out.println(parseClientServiceCommonParam("nullnullANDROIDLVMM8633600202168124.4.4nullnullnull7.5.0nullnullff60f4c7-69d4-430f-8dce-560aeb4f7f85nullapi.com.order.getOrder2.0.0nullnullnull"));
		
		
//		String temp = getThreadName("2016-04-13 17:22:32,018 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		System.out.println(temp);
//		System.out.println(isFlumeThreadName(temp));
		
//		System.out.println(parseStringToLong("FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd297"));
//		System.out.println(parseStringToLong("FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298"));
//		System.out.println(parseStringToLong("FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd299"));
//		System.out.println(parseStringToLong("FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd29a"));
//		System.out.println(parseStringToLong("FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd2a9"));
//		System.out.println(parseStringToLong("FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc13fd29a"));
		
//		String result = logEncode("2016-04-13 17:22:32,018 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		System.out.println(result);
//		System.out.println(logDecode(result));
		
//		List<String> logList = new ArrayList<String>();
//		logList.add("2016-04-13 17:22:32,018 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		logList.add("2016-04-13 17:22:32,018 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		logList.add("2016-04-13 17:22:32,018 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		
//		String dd = concatLog(logList, ",");
//		System.out.println(dd);
//		String gzipStr = gzip(dd);
//		System.out.println(gzipStr);
//		System.out.println(gunzip(gzipStr));
//		logList = splitLog(gunzip(gzipStr), ",");
//		for(String str: logList){
//			System.out.println(str);
//		}
		
//		Date date = getPrintDate("2016-04-24 12:07:59,315 INFO  client-service [FLUME-9336c852-15ab-4d74-af41-6238f7586c8d] (ForceUpgradeInterceptor.java:74) - lvversion = 7.5.0,firstChannel = ANDROID-------------------");
//		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,S");
//		System.out.println(format.format(date));
		
//		LogInfo logInfo = parseLog("2016-04-13 17:22:32,008 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		System.out.println(logInfo);
		
		
//		List<String> logList = new ArrayList<String>();
//		logList.add("2016-04-13 17:22:32,018 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		logList.add("2016-04-13 17:22:32,019 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		logList.add("2016-04-13 17:22:32,022 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - FLUME-LOG-END");
//		logList.add("2016-04-13 17:22:32,022 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		logList.add("2016-04-13 17:22:32,022 INFO  client-service [FLUME-d3d04cd3-8f38-4dc8-b03f-30dcc31fd298] (ForceUpgradeInterceptor.java:74) - lvversion = null,firstChannel = null-------------------");
//		
//		System.out.println(isCompleteLog(logList));
		
//		int i = -50;
//		int j = -i;
//		System.out.println(j);
		
//		List<String> result = parseClientServiceSpecialParam("1");
//		for(String s : result) {
//			System.out.println(s);
//		}
		
//		
//		System.out.println(isDubboMethodEndLogContent("interface = interface com.lvmama.comm.tnt.service.TntSellPackageService, method = getSellPackageListByChannel -- end"));
//		System.out.println(isDubboMethodStartLogContent("interface = interface com.lvmama.comm.tnt.service.TntSellPackageService, method = getSellPackageListByChannel -- start"));
		
		System.out.println(isNeed("2016-05-30 23:50:55,639 INFO[LvLogS]client-service [FLUME-e981c8f6-1624-4fde-88ce-8837b9785c4d] (TntCacheAspect.java:59) - cacheKey=[LVTU_API_TICKET_GETTICKETGOODSVO_571807],cachSeconds=[600]"));
	}
}
